﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Search.Linq;

namespace UnitTest
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class SystemIndexTest
    {
        static SystemIndex<SystemSearch> systemIndex ;
        public SystemIndexTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
         [ClassInitialize()]
         public static void MyClassInitialize(TestContext testContext) { 
         
             systemIndex = new SystemIndex<SystemSearch>();

         
         }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { 
         
        // }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestSimpleSearch()
        {
            var result = (from SystemSearch t in systemIndex
                         select new { t.ItemName, t.Author,t.Shell, t.Kind, t.Language });

            if (result.First() == null)
            {
                throw new Exception("Some value expected");
            }
            

        }

        [TestMethod]
        public void TestWhereSearch()
        {

            var result = (from SystemSearch t in systemIndex
                          where t.Kind == new string [] {"document"} ||
                                t.Kind == new string[] { "folder" }
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            foreach (var item in result)
            {
                TestContext.WriteLine(item.ItemName);
            }

        }

        [TestMethod]
        public void TestOrderBySearch()
        {
            var result = (from SystemSearch t in systemIndex
                          orderby t.Language
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            foreach (var item in result)
            {
                TestContext.WriteLine(item.ItemName);
            }
            
            

        }

        [TestMethod]
        public void TestFirstMethod()
        {
            var result = (from SystemSearch t in systemIndex
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            var item = result.First();
            if (item != null)
                TestContext.WriteLine(item.ItemName);

        }

        public string getStr()
        {
            return "Nothing to constain";
        }

        [TestMethod]
        public void TestFirstMethodNoResults()
        {
            var containStr = "Nothing to constain";
            var result = (from SystemSearch t in systemIndex
                          where t.ItemName.Contains(this.getStr())
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            try
            {
                var item = result.First();
                if (item != null)
                    TestContext.WriteLine(item.ItemName);
                
            }
            catch (EmptySecuenceError)
            { 
            
            }
            
            
        }
        [TestMethod]
        public void TestFirstOrDefaultNoResult()
        {
            var result = (from SystemSearch t in systemIndex
                          where t.ItemName.Contains("Nothing to constain")
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            var item = result.FirstOrDefault();
            if (item != null)
                TestContext.WriteLine(item.ItemName);

        }
        [TestMethod]
        public void TestFirstOrDefault()
        {
            var result = (from SystemSearch t in systemIndex
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            var item = result.FirstOrDefault();
            if (item != null)
                TestContext.WriteLine(item.ItemName);

        }

        [TestMethod]
        public void TestSkipAndTake()
        {
            var result = (from SystemSearch t in systemIndex
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            result = result.Skip(10).Take(10);
            
            int i = 0;
            foreach (var item in result)
            {
                i++;
                TestContext.WriteLine(item.ItemName);
            }

            if (i!=10){
               throw new Exception("Invalid result count");
            }

        }

        [TestMethod]
        public void TestSkipAndTakeNoResult()
        {
            var result = (from SystemSearch t in systemIndex
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            result = result.Take(10).Skip(11);
            var enumerator = result.GetEnumerator();

            // At this moment  TAKE.SPKIP = SKIP.TAKE
            // See how to fix this issue
            if (enumerator.MoveNext())
            {
                throw new Exception("Invalid result count");
            }

        }

        [TestMethod]
        public void TestSkipWhile()
        {
            var result = (from SystemSearch t in systemIndex
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

             result = result.SkipWhile(t => t.Kind == new string[] { "No Element" });

             if (!result.GetEnumerator().MoveNext())
                 throw new Exception(" Elements expected ... 0 elements found");


        }

        [TestMethod]
        public void TestSkipWhileNoElements()
        {
            var result = (from SystemSearch t in systemIndex
                          where t.Kind == new string[] { "folder" }
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            result = result.SkipWhile(t => t.Kind == new string[] { "folder" });

            if (!result.GetEnumerator().MoveNext())
                throw new Exception(" No elements expected ...");

        }


       /* [TestMethod]
        public void TestDebuguerVisualizer()
        {
            var result = (from SystemSearch t in systemIndex
                          select new { t.ItemName, t.Author, t.Kind, t.Language });

            SystemIndexListQueryVisualizer.TestShowVisualizer(result);

        }*/
    }
}
